package com.ums.upos.service;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Base64;
import android.view.WindowManager;

import com.nexgo.common.ByteUtils;
import com.nexgo.oaf.apiv3.SdkResult;
import com.nexgo.oaf.apiv3.device.pinpad.OnPinPadInputListener;
import com.nexgo.oaf.apiv3.device.pinpad.PinPad;
import com.nexgo.oaf.apiv3.device.reader.CardInfoEntity;
import com.nexgo.oaf.apiv3.emv.CandidateAppInfoEntity;
import com.nexgo.oaf.apiv3.emv.EmvAlgorithmTypeEnum;
import com.nexgo.oaf.apiv3.emv.EmvCardLogEntity;
import com.nexgo.oaf.apiv3.emv.EmvChannelTypeEnum;
import com.nexgo.oaf.apiv3.emv.EmvDataSourceEnum;
import com.nexgo.oaf.apiv3.emv.EmvOnlineResultEntity;
import com.nexgo.oaf.apiv3.emv.EmvProcessResultEntity;
import com.nexgo.oaf.apiv3.emv.EmvTransDataEntity;
import com.nexgo.oaf.apiv3.emv.EmvTransFlowEnum;
import com.nexgo.oaf.apiv3.emv.QpbocErrCodeEnum;
import com.ums.upos.GlobalDataHolder;
import com.ums.upos.service.ui.PinInputDialog;
import com.ums.upos.uapi.R;
import com.ums.upos.uapi.ServiceResult;
import com.ums.upos.uapi.device.pinpad.PinPadKeyCode;
import com.ums.upos.uapi.emv.EmvAidPara;
import com.ums.upos.uapi.emv.EmvCapk;
import com.ums.upos.uapi.emv.EmvCardLog;
import com.ums.upos.uapi.emv.EmvChannelType;
import com.ums.upos.uapi.emv.EmvDataSource;
import com.ums.upos.uapi.emv.EmvHandler;
import com.ums.upos.uapi.emv.EmvOnlineRequest;
import com.ums.upos.uapi.emv.EmvOnlineResult;
import com.ums.upos.uapi.emv.EmvProcessResult;
import com.ums.upos.uapi.emv.EmvTermCfgConstrants;
import com.ums.upos.uapi.emv.EmvTransDataConstrants;
import com.ums.upos.uapi.emv.EmvTransFlow;
import com.ums.upos.uapi.emv.OnEmvProcessListener;
import com.ums.upos.util.FileUtils;
import com.ums.upos.util.PinPadUtils;
import com.ums.upos.util.SharedPreferencesUtil;
import com.ums.upos.util.XMLBuilder;
import com.ums.upos.util.XmlCreater;
import com.ums.upos.util.XmlOper;

import org.greenrobot.eventbus.EventBus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


/**
 * Created by xiaox on 15-10-7.
 */
public class EmvBinder extends EmvHandler.Stub {
    private final String TAG = "Emv";
    private final Context context;
    private final Logger log;
    private com.nexgo.oaf.apiv3.emv.EmvHandler sdkEmvHandler;
    private PinPad sdkPinPad;
    private String mBussinessId;
    private int mWorkMode;
    private String mAmount;
    private boolean mIsNeedPan;

    EmvBinder(Context context) {
        mWorkMode = GlobalDataHolder.getInstance().getWorkMode();
        mBussinessId = GlobalDataHolder.getInstance().getBussinessId();
        sdkEmvHandler = GlobalDataHolder.getInstance().getDeviceEngine().getEmvHandler(mBussinessId);
//        sdkPinPad = GlobalDataHolder.getInstance().getDeviceEngine().getPinPad();
//        sdkEmvHandler.emvDebugLog(true);
        sdkPinPad = GlobalDataHolder.getInstance().getSdkPinpad();
        this.context = context;
        log = LoggerFactory.getLogger(TAG);
    }

    private EmvTransDataEntity getEmvTransData(Bundle data) {
        EmvTransDataEntity emvTransDataEntity = new EmvTransDataEntity();
        emvTransDataEntity.setIsSupportEC(data.getBoolean(EmvTransDataConstrants.ISSUPPORTEC, false));
        EmvTransFlowEnum emvTransFlowEnum;
        switch (data.getInt(EmvTransDataConstrants.PROCTYPE)) {
            case EmvTransFlow.SIMPLE:
                emvTransFlowEnum = EmvTransFlowEnum.SIMPLE;
                break;
            case EmvTransFlow.QPASS:
                emvTransFlowEnum = EmvTransFlowEnum.QPASS;
                break;
            case EmvTransFlow.FULL:
            default:
                emvTransFlowEnum = EmvTransFlowEnum.FULL;
                break;
        }
        emvTransDataEntity.setProcType(emvTransFlowEnum);
        Object obj = data.get(EmvTransDataConstrants.ISQPBOCFORCEONLINE);
        boolean isQpbocForceLine;
        if (obj instanceof Integer) {
            isQpbocForceLine = (Integer) obj == 1;
        } else if (obj instanceof Boolean) {
            isQpbocForceLine = (Boolean) obj;
        } else {
            isQpbocForceLine = false;
        }
        emvTransDataEntity.setIsForceOnline(isQpbocForceLine);
//        emvTransDataEntity.setIsForceOnline(true);
        emvTransDataEntity.setTransAmt(data.getString(EmvTransDataConstrants.TRANSAMT));
        emvTransDataEntity.setB9C(data.getByte(EmvTransDataConstrants.B9C));
        EmvChannelTypeEnum emvChannelTypeEnum;
        switch (data.getInt(EmvTransDataConstrants.CHANNELTYPE)) {
            case EmvChannelType.FROM_PICC:
                emvChannelTypeEnum = EmvChannelTypeEnum.FROM_PICC;
                break;
            case EmvChannelType.FROM_ICC:
            default:
                emvChannelTypeEnum = EmvChannelTypeEnum.FROM_ICC;
                break;
        }
        emvTransDataEntity.setChannelType(emvChannelTypeEnum);
        emvTransDataEntity.setMerId(data.getString(EmvTransDataConstrants.MERID));
        emvTransDataEntity.setMerName(data.getString(EmvTransDataConstrants.MERNAME));
        emvTransDataEntity.setTraceNo(data.getString(EmvTransDataConstrants.SEQNO));
        emvTransDataEntity.setCashbackAmt(data.getString(EmvTransDataConstrants.CASHBACKAMT));
        emvTransDataEntity.setTransDate(data.getString(EmvTransDataConstrants.TRANSDATE));
        emvTransDataEntity.setTransTime(data.getString(EmvTransDataConstrants.TRANSTIME));
        emvTransDataEntity.setTermId(data.getString(EmvTransDataConstrants.TERMID));

        Object bundleIsSM = data.get(EmvTransDataConstrants.ISSUPPORTCHINESECRYPTALG);
        EmvAlgorithmTypeEnum eAlgType = EmvAlgorithmTypeEnum.RSA;
        if (bundleIsSM instanceof Integer) {
            if ((Integer) bundleIsSM == 1)
                eAlgType = EmvAlgorithmTypeEnum.SM2;
        } else if (bundleIsSM instanceof Boolean) {
            if ((Boolean) bundleIsSM)
                eAlgType = EmvAlgorithmTypeEnum.SM2;
        }
        emvTransDataEntity.setAlgType(eAlgType);
        return emvTransDataEntity;
    }

    private String getCardNo() {
        byte[] data;
        String cardNo;
        data = sdkEmvHandler.getTlv(new byte[]{(byte) 0x5a}, EmvDataSourceEnum.FROM_KERNEL);
        if (data == null) {
            log.debug("5a null");
            data = sdkEmvHandler.getTlv(new byte[]{(byte) 0x57}, EmvDataSourceEnum.FROM_KERNEL);
            if (data == null) {
                log.debug("57 null");
                return null;
            }
            cardNo = ByteUtils.byteArray2HexString(data);
            cardNo = cardNo.replace('=', 'd');
            if (cardNo.toLowerCase().contains("d")) {
                cardNo = cardNo.substring(0, cardNo.indexOf("d"));
            }
        } else {
            cardNo = ByteUtils.byteArray2HexString(data);
        }
        if (cardNo.toLowerCase().endsWith("f")) {
            cardNo = cardNo.substring(0, cardNo.length() - 1);
        }
        log.debug("cardNo {} **** **** **** {}", cardNo.substring(0, 4), cardNo.substring(cardNo.length() - 2));
        return cardNo;
    }

    private PinPadUtils.OnPinInputListener mOnPinInputListener = new PinPadUtils.OnPinInputListener() {
        @Override
        public void onInputResult(int serviceResult, byte[] enPinData) {
//            if (serviceResult == SdkResult.Success) {
            if (serviceResult == ServiceResult.Success) {
                sdkEmvHandler.setTlv(new byte[]{(byte) 0xdf, (byte) 0x36}, enPinData);
                sdkEmvHandler.onSetPinInputResponse(true, false);
//            } else if (serviceResult == SdkResult.PinPad_No_Pin_Input) {
            } else if (serviceResult == ServiceResult.PinPad_No_Pin_Input) {
                sdkEmvHandler.setTlv(new byte[]{(byte) 0xdf, (byte) 0x36}, new byte[8]);
                sdkEmvHandler.onSetPinInputResponse(true, true);
            } else {
                sdkEmvHandler.onSetPinInputResponse(false, false);
            }
        }

        @Override
        public void onSendKey(byte keyCode) {

        }
    };

    int getDefaultSelAppIndex(List<CandidateAppInfoEntity> sdklist) {
        int CupAidCnt = 0;
        int selectindex = 0;
        String CupAid = "A000000333";
//        log.debug("onSelApp CupAid:{}", CupAid);
        for (int i = 0; i < sdklist.size(); i++) {
            CandidateAppInfoEntity appInfoEntity = sdklist.get(i);
            byte[] aidBytes = appInfoEntity.getAid();
            log.debug("onSelApp index:{},aidBytes:{}", i, aidBytes);
            if (aidBytes.length > 0) {
                String aid = ByteUtils.asciiByteArray2String1(aidBytes);
                log.debug("onSelApp aid:{}", aid);
                if (true == CupAid.equals(aid.substring(0, 10))) {
                    CupAidCnt++;
                    selectindex = i + 1;
                }
            }
        }
        log.debug("onSelApp CupAidCnt:{},selectindex:{}", CupAidCnt, selectindex);
        if (CupAidCnt == 1)
            return selectindex;

        return 0;
    }

    @Override
    public int emvProcess(Bundle data, final OnEmvProcessListener listener) throws RemoteException {
        log.info("call emvProcess");
        if (data == null || listener == null) return ServiceResult.Param_In_Invalid;

        log.info("emvProcess----Bundle data:"+data);
        for (String str : data.keySet()) {
            if (data.get(str) instanceof byte[]) {
                log.debug("key {},byte[] value {}", str, ByteUtils.byteArray2HexString(data.getByteArray(str)));
            } else {
                log.debug("key {},value {}", str, data.get(str));
            }
        }
        List<String> checkParamList = new ArrayList<>();
        checkParamList.add(EmvTransDataConstrants.B9C);
        checkParamList.add(EmvTransDataConstrants.PROCTYPE);
        checkParamList.add(EmvTransDataConstrants.TRANSAMT);
        checkParamList.add(EmvTransDataConstrants.MKEYIDX);
        checkParamList.add(EmvTransDataConstrants.TRANSAMT);
//        checkParamList.add(EmvTransDataConstrants.TRANSDATE);
//        checkParamList.add(EmvTransDataConstrants.TRANSTIME);
        checkParamList.add(EmvTransDataConstrants.CHANNELTYPE);
        checkParamList.add(EmvTransDataConstrants.MKEYIDX);

        for (String key : checkParamList) {
            if (!data.containsKey(key)) {
                return ServiceResult.Param_In_Invalid;
            }
        }

        if (data.getInt(EmvTransDataConstrants.PROCTYPE) == EmvTransFlow.QPASS
                && data.getInt(EmvTransDataConstrants.CHANNELTYPE) != EmvChannelType.FROM_PICC) {
            return ServiceResult.Param_In_Invalid;
        }
        final int mKeyIdx = data.getInt(EmvTransDataConstrants.MKEYIDX);
        mAmount = data.getString(EmvTransDataConstrants.TRANSAMT, "000000000000");
        //传统模式下无此key为要主帐号加密，手机模式下无此key表示不要主帐号加密
        mIsNeedPan = data.getBoolean(EmvTransDataConstrants.ISNEEDPAN, mWorkMode == 0);

        final boolean isEcTrans = data.getBoolean(EmvTransDataConstrants.ISSUPPORTEC, false);
        Object obj = data.get(EmvTransDataConstrants.ISQPBOCFORCEONLINE);
        final boolean isQpbocForceLine;
        if (obj instanceof Integer) {
            isQpbocForceLine = (Integer) obj == 1;
        } else if (obj instanceof Boolean) {
            isQpbocForceLine = (Boolean) obj;
        } else {
            isQpbocForceLine = false;
        }
        final boolean isQPBOC = data.getInt(EmvTransDataConstrants.PROCTYPE) == EmvTransFlow.QPASS
                && isEcTrans
                && !isQpbocForceLine;
        final boolean isQPBOCOnline = data.getInt(EmvTransDataConstrants.PROCTYPE) == EmvTransFlow.QPASS && isQpbocForceLine;
        int channelType = data.getInt(EmvTransDataConstrants.CHANNELTYPE, 0);
//        if (channelType == EmvChannelType.FROM_PICC) {
//            sdkCPUcardHandler = GlobalDataHolder.getInstance().getDeviceEngine().getCPUCardHandler(CardSlotTypeEnum.RF);
//            sdkCPUcardHandler.active();
//        } else {
//            sdkCPUcardHandler = GlobalDataHolder.getInstance().getDeviceEngine().getCPUCardHandler(CardSlotTypeEnum.ICC1);
//            sdkCPUcardHandler.powerOn(new byte[64]);
//        }

        int result = sdkEmvHandler.emvProcess(getEmvTransData(data), new com.nexgo.oaf.apiv3.emv.OnEmvProcessListener() {

            @Override
            public void onRequestAmount() {

            }

            @Override
            public void onSelApp(List<String> list, List<CandidateAppInfoEntity> list1, boolean b) {
                log.info("call emvProcess onSelApp");
                int defaultSelAppIndex = getDefaultSelAppIndex(list1);
                if (defaultSelAppIndex > 0)
                    sdkEmvHandler.onSetSelAppResponse(defaultSelAppIndex);
                else {
                    try {
                        listener.onSelApp(list, b);
                    } catch (RemoteException e) {
                        sdkEmvHandler.onSetSelAppResponse(-1);
                    }
                }
            }

            @Override
            public void onConfirmEcSwitch() {
                log.info("call emvProcess onConfirmEcSwitch");
                sdkEmvHandler.onSetConfirmEcSwitchResponse(isEcTrans);
            }

            @Override
            public void onConfirmCardNo(CardInfoEntity cardInfoEntity) {
                log.info("call emvProcess onConfirmCardNo");
                try {
                    if (isQPBOC) {
                        sdkEmvHandler.onSetConfirmCardNoResponse(true);
                        return;
                    }
                    listener.onConfirmCardNo(cardInfoEntity.getCardNo());
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onCardHolderInputPin(boolean b, int i) {
                log.info("call emvProcess onCardHolderInputPin");
                try {
                    if (isQpbocForceLine) {
                        //执行OnEmvProcessListener. onCardHolderInputPin方法后调用，通知emv内核继续流程
                        sdkEmvHandler.onSetPinInputResponse(true, true);
                        return;
                    }
                    log.debug("emvProcess onCardHolderInputPin setShowAmount, mAmount:{}", mAmount);
                    GlobalDataHolder.getInstance().setShowAmount(mAmount);
                    listener.onCardHolderInputPin(b, i);
                    byte[] supportPinLen = null;
                    int[] pinLen = null;
                    int timeout = SharedPreferencesUtil.getInstance(context).getInt("pinTimeout", 60);
                    String str = SharedPreferencesUtil.getInstance(context).getString("supportpinlen", null);
                    if (str != null) {
                        supportPinLen = Base64.decode(str.getBytes(), Base64.DEFAULT);
                        if (supportPinLen != null) {
                            pinLen = new int[supportPinLen.length];
                            for (int j = 0; j < supportPinLen.length; j++) {
                                pinLen[j] = supportPinLen[j];
                            }
                        }
                    }
                    if (pinLen == null) {
                        pinLen = new int[]{0, 4, 5, 6, 7, 8, 9, 10, 11, 12};
                    }
                    int result = ServiceResult.Fail;
                    if (b) {
                        String cardNo = getCardNo();
                        if (cardNo != null) {
                            if (mWorkMode == 0) {
                                byte[] zeroCardNo = new byte[13];
                                Arrays.fill(zeroCardNo, (byte) 0x30);
                                result = PinPadUtils.inputOnlinePin(pinLen, timeout, context, mIsNeedPan ? getCardNo().getBytes() : zeroCardNo, mKeyIdx, mOnPinInputListener);
                            } else {
                                result = PinPadUtils.inputMobileModeOnlinePin(mIsNeedPan ? getCardNo().getBytes() : null, timeout, context, mOnPinInputListener);
                            }
                        }
                        if (result != ServiceResult.Success) {
                            sdkEmvHandler.onSetPinInputResponse(false, false);
                        }
                    } else {
                        result = sdkPinPad.inputOfflinePin(pinLen, timeout, new OnPinPadInputListener() {
                            @Override
                            public void onInputResult(int i, byte[] bytes) {
                                log.debug("emvProcess onCardHolderInputPin inputOfflinePin onInputResult i:{},bytes{}", i, bytes);
                                if (i == ServiceResult.Success) {
                                    EventBus.getDefault().post(new PinKeyCodeEvent(PinPadKeyCode.KEYCODE_CONFIRM));
                                } else {
                                    EventBus.getDefault().post(new PinKeyCodeEvent(PinPadKeyCode.KEYCODE_CANCEL));
                                }
                                if (i == SdkResult.Success) {
                                    sdkEmvHandler.onSetPinInputResponse(true, false);
                                } else if (i == SdkResult.PinPad_No_Pin_Input) {
                                    sdkEmvHandler.onSetPinInputResponse(true, true);
                                } else {
                                    sdkEmvHandler.onSetPinInputResponse(false, false);
                                }
                            }

                            @Override
                            public void onSendKey(byte b) {
                                EventBus.getDefault().post(new PinKeyCodeEvent(b));
                            }
                        });
                        if (result == SdkResult.Success) {
                            //发起输入密码界面
                            new Handler(Looper.getMainLooper()).post(new Runnable() {
                                @Override
                                public void run() {
                                    PinInputDialog pinInputDialog = new PinInputDialog(context, R.style.CustomDialog);
                                    pinInputDialog.getWindow().setType((WindowManager.LayoutParams.TYPE_SYSTEM_ALERT));
                                    pinInputDialog.setCanceledOnTouchOutside(false);
                                    pinInputDialog.show();
                                    pinInputDialog.setInputPinType(false);
                                }
                            });
                        } else {
                            sdkEmvHandler.onSetPinInputResponse(false, false);
                        }
                    }
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onCertVerify(String s, String s1) {
                log.info("call emvProcess onCertVerify");
                try {
                    listener.onCertVerify(s, s1);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onOnlineProc() {
                log.info("call emvProcess onOnlineProc");
                byte[] pin;
                byte[] cardSn;
                Bundle bundle = new Bundle();
                pin = sdkEmvHandler.getTlv(new byte[]{(byte) 0xdf, (byte) 0x36}, EmvDataSourceEnum.FROM_KERNEL);
                bundle.putByteArray(EmvOnlineRequest.PIN, pin);
                cardSn = sdkEmvHandler.getTlv(new byte[]{(byte) 0x5f, (byte) 0x34}, EmvDataSourceEnum.FROM_KERNEL);
                bundle.putByteArray(EmvOnlineRequest.CARDSN, cardSn);
                try {
                    listener.onOnlineProc(bundle);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onReadCardAgain() {
                log.info("call emvProcess onReadCardAgain");
                sdkEmvHandler.onSetReadCardAgainResponse(true);
            }

            @Override
            public void onAfterFinalSelectedApp() {
                log.info("call emvProcess onAfterFinalSelectedApp");
                sdkEmvHandler.onSetAfterFinalSelectedAppResponse(true);
            }

            @Override
            public void onFinish(int i, EmvProcessResultEntity emvProcessResultEntity) {
                log.info("call emvProcess onFinish, i:{}", i);
                try {
                    if (i == SdkResult.Success) {
                        if (emvProcessResultEntity != null) {
                            byte[] script = emvProcessResultEntity.getScriptResult();
                            log.debug("emvProcess onFinish script:{}", script);
                            if (script != null) {
                                Bundle bundle = new Bundle();
                                bundle.putByteArray(EmvProcessResult.SCRIPTRESULT, script);
                                listener.onFinish(emvResultConvert(i), bundle);
                                return;
                            }
                        }
                    }
                    listener.onFinish(emvResultConvert(i), null);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
//                finally {
//                    mIsBusy = false;
//                }
            }
        });
        if (result == SdkResult.Success) {
            return ServiceResult.Success;
        } else {
            return ServiceResult.Fail;
        }
    }

    private int emvResultConvert(int sdkResult) {
        int result;
        switch (sdkResult) {
            case SdkResult.Emv_Other_Interface:
                result = ServiceResult.Emv_Other_Interface;
                break;
            case SdkResult.Emv_Qpboc_Offline:
                result = ServiceResult.Emv_Qpboc_Offline;
                break;
            case SdkResult.Emv_Qpboc_Online:
                result = ServiceResult.Emv_Qpboc_Online;
                break;
            case SdkResult.Emv_Pboc_Online:
                result = ServiceResult.Emv_Pboc_Online;
                break;
            case SdkResult.Emv_MSD_Online:
                result = ServiceResult.Emv_MSD_Online;
                break;
            case SdkResult.Emv_Ec_Accept:
                result = ServiceResult.Emv_Ec_Accept;
                break;
            case SdkResult.Emv_Offline_Accept:
                result = ServiceResult.Emv_Offline_Accept;
                break;
            case SdkResult.Emv_Card_Removed:
                result = ServiceResult.Emv_Card_Removed;
                break;
            case SdkResult.Emv_Command_Fail:
                result = ServiceResult.Emv_Command_Fail;
                break;
            case SdkResult.Emv_Card_Block:
                result = ServiceResult.Emv_Card_Block;
                break;
            case SdkResult.Emv_PARA_ERR:
                result = ServiceResult.Emv_PARA_ERR;
                break;
            case SdkResult.Emv_Candidatelist_Empty:
                result = ServiceResult.Emv_Candidatelist_Empty;
                break;
            case SdkResult.Emv_App_Block:
                result = ServiceResult.Emv_App_Block;
                break;
            case SdkResult.Emv_FallBack:
                result = ServiceResult.Emv_FallBack;
                break;
            case SdkResult.Emv_Auth_Fail:
                result = ServiceResult.Emv_Auth_Fail;
                break;
            case SdkResult.Emv_App_Ineffect:
                result = ServiceResult.Emv_App_Ineffect;
                break;
            case SdkResult.Emv_App_Expired:
                result = ServiceResult.Emv_App_Expired;
                break;
            case SdkResult.Emv_Cvm_Fail:
                result = ServiceResult.Emv_Cvm_Fail;
                break;
            case SdkResult.Emv_Online:
                result = ServiceResult.Emv_Online;
                break;
            case SdkResult.Emv_Cancel:
                result = ServiceResult.Emv_Cancel;
                break;
            case SdkResult.Emv_Declined:
                result = ServiceResult.Emv_Declined;
                break;
            case SdkResult.Emv_Arpc_Fail:
                result = ServiceResult.Emv_Arpc_Fail;
                break;
            case SdkResult.Emv_Script_Fail:
                result = ServiceResult.Emv_Script_Fail;
                break;
            case SdkResult.Emv_App_NoAccept:
                result = ServiceResult.Emv_App_NoAccept;
                break;
            case SdkResult.Emv_Offline_Declined:
                result = ServiceResult.Emv_Ec_Decliend;
                break;
            case SdkResult.Emv_Other_Error:
                result = ServiceResult.Emv_Other_Error;
                break;
            case SdkResult.Emv_Success_Arpc_Fail:
            case SdkResult.Success:
                result = ServiceResult.Success;
                break;
            default:
                result = ServiceResult.Fail;
                break;
        }
        log.debug("call emvResultConvert sdkResult:{},result:{}", sdkResult, result);
        return result;
    }

    /**
     * 初始化终端参数
     * @param cfg
     * @return
     * @throws RemoteException
     */
    @Override
    public int initTermConfig(Bundle cfg) throws RemoteException {
        log.info("call initTermConfig");
        if (cfg == null) return ServiceResult.Param_In_Invalid;

        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            for (String key : cfg.keySet()) {
                if (cfg.get(key) instanceof byte[]) {
                    log.debug("key {},value {}", key, ByteUtils.byteArray2HexString(cfg.getByteArray(key)));
                } else {
                    log.debug("key {},value {}", key, cfg.get(key));
                }

                byte[] tlv;
                switch (key) {
                    case EmvTermCfgConstrants.TERMCAP:
                        tlv = ByteUtils.getTLVData("9F33", cfg.getByteArray(key).length, cfg.getByteArray(key));
                        bos.write(tlv);
                        break;
                    case EmvTermCfgConstrants.ADDTERMCAP:
                        tlv = ByteUtils.getTLVData("9F40", cfg.getByteArray(key).length, cfg.getByteArray(key));
                        bos.write(tlv);
                        break;
                    case EmvTermCfgConstrants.IFDSEQNO:
                        tlv = ByteUtils.getTLVData("9F1E",
                                cfg.getByteArray(key).length > 8 ? 8 : cfg.getByteArray(key).length,
                                cfg.getByteArray(key));
                        bos.write(tlv);
                        break;
                    case EmvTermCfgConstrants.COUNTRYCODE:
                        tlv = ByteUtils.getTLVData("9F1A", cfg.getByteArray(key).length, cfg.getByteArray(key));
                        bos.write(tlv);
                        break;
                    case EmvTermCfgConstrants.TERMID:
                        tlv = ByteUtils.getTLVData("9F1C", cfg.getByteArray(key).length, cfg.getByteArray(key));
                        bos.write(tlv);
                        break;
                    case EmvTermCfgConstrants.TERMTYPE:
                        tlv = ByteUtils.getTLVData("9F35", 1, new byte[]{cfg.getByte(key)});
                        bos.write(tlv);
                        break;
                    case EmvTermCfgConstrants.CURRENCYCODE:
                        tlv = ByteUtils.getTLVData("5F2A", cfg.getByteArray(key).length, cfg.getByteArray(key));
                        bos.write(tlv);
                        break;
                }
            }
            byte[] mergeTlv = bos.toByteArray();
            bos.close();
            log.debug("mergeTlv:" + ByteUtils.byteArray2HexStringWithSpace(mergeTlv));
            int result = sdkEmvHandler.initTermConfig(mergeTlv);
            if (result == SdkResult.Success) {
                return ServiceResult.Success;
            } else {
                return ServiceResult.Fail;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ServiceResult.Fail;
    }

    /**
     * 加载EMV参数列表
     * @param aidParaList
     * @return
     * @throws RemoteException
     */
    @Override
    public int setAidParaList(List<EmvAidPara> aidParaList) throws RemoteException {
        log.info("call setAidParaList");
        try {
            if (aidParaList == null || aidParaList.size() == 0) {
                return ServiceResult.Param_In_Invalid;
            }

            String bussinessId = mBussinessId;
            String filesPath = context.getFilesDir().getAbsolutePath();
            String dirPath1 = filesPath + "/emv_data/";
            if (!FileUtils.isFileExist(dirPath1)) {
                log.debug("dirPath1 not exist,creat dirPath1:" + dirPath1);
                FileUtils.newFolder(dirPath1);
            }
            String dirPath2 = dirPath1 + bussinessId;
            if (!FileUtils.isFileExist(dirPath2)) {
                log.debug("dirPath2 not exist,creat dirPath2:" + dirPath2);
                FileUtils.newFolder(dirPath2);
            }
//            String filePath = dirPath2 + "/emv_file.xml";
            String filePath = dirPath2 + "/emv_aid_file.xml";
            XmlCreater xmlCreater = new XmlCreater(filePath);
            Element aidElement;
            Element emv = xmlCreater.createRootElement("emv");
            if (!FileUtils.isFileExist(filePath)) {
                log.debug("recreate emv.xml");
                aidElement = xmlCreater.createElement(emv, "aidElement");
            } else {
                log.debug("modify xml");
                //获取XML的dom
                Document doc = xmlCreater.getDoc();
                //获取根节点下的指定子节点列表
                Element[] cfgs = XmlOper.getElementsByName(emv, "aidElement");

                if (cfgs.length > 0) {
                    aidElement = cfgs[0];
                    //删除aid节点下所有子节点
                    XmlOper.removeElement(aidElement, "aidItem");
                } else {
                    //新建aid节点
                    aidElement = xmlCreater.createElement(emv, "aidElement");
                }
                //设置dom
                xmlCreater.setDoc(doc);
            }
            log.debug("add aid count:" + aidParaList.size());
            List<byte[]> aidList = new ArrayList<>();
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            for (EmvAidPara emvAidPara : aidParaList) {
                if (emvAidPara.getAID() == null || emvAidPara.getDDOL() == null) {
                    return ServiceResult.Emv_PARA_ERR;
                }
                bos.reset();
                byte[] _9F06 = ByteUtils.getTLVData("9F06", emvAidPara.getAID_Length(), emvAidPara.getAID());
                bos.write(_9F06);

                byte[] _DF01 = ByteUtils.getTLVData("DF01", 1, new byte[]{emvAidPara.getAppSelIndicator()});
                bos.write(_DF01);

                String str = ByteUtils.byteArray2HexString(emvAidPara.getTermAppVer());
                byte[] bcd;
                //有时候是asc码，有时候是bcd码
                if (!str.contains("00")) {
                    bcd = ByteUtils.str2Bcd(ByteUtils.asciiByteArray2String(emvAidPara.getTermAppVer()));
                } else {
                    bcd = emvAidPara.getTermAppVer();
                }
                byte[] _9F09 = ByteUtils.getTLVData("9F09", 2, bcd);
                bos.write(_9F09);

                byte[] _DF11 = ByteUtils.getTLVData("DF11", emvAidPara.getTAC_Default().length, emvAidPara.getTAC_Default());
                bos.write(_DF11);

                byte[] _DF12 = ByteUtils.getTLVData("DF12", emvAidPara.getTAC_Online().length, emvAidPara.getTAC_Online());
                bos.write(_DF12);

                byte[] _DF13 = ByteUtils.getTLVData("DF13", emvAidPara.getTAC_Denial().length, emvAidPara.getTAC_Denial());
                bos.write(_DF13);

                byte[] _9F1B;
                byte[] _DF15;
                byte[] _DF16;
                byte[] _DF17;
                if (ByteUtils.byteArray2HexString(emvAidPara.getAID()).substring(0, 10).equals("a000000333")) {//国内
                    _9F1B = ByteUtils.getTLVData("9F1B", emvAidPara.getTFL_Domestic().length, emvAidPara.getTFL_Domestic());
                    _DF15 = ByteUtils.getTLVData("DF15", emvAidPara.getThresholdValueDomestic().length, emvAidPara.getThresholdValueDomestic());
                    _DF16 = ByteUtils.getTLVData("DF16", 1, new byte[]{emvAidPara.getMaxTargetDomestic()});
                    _DF17 = ByteUtils.getTLVData("DF17", 1, new byte[]{emvAidPara.getTargetPercentageDomestic()});
                } else {//国际
                    _9F1B = ByteUtils.getTLVData("9F1B", emvAidPara.getTFL_International().length, emvAidPara.getTFL_International());
                    _DF15 = ByteUtils.getTLVData("DF15", emvAidPara.getThresholdValueInt().length, emvAidPara.getThresholdValueInt());
                    _DF16 = ByteUtils.getTLVData("DF16", 1, new byte[]{emvAidPara.getMaxTargetPercentageInt()});
                    _DF17 = ByteUtils.getTLVData("DF17", 1, new byte[]{emvAidPara.getTargetPercentageInt()});
                }
                bos.write(_9F1B);
                bos.write(_DF15);
                bos.write(_DF16);
                bos.write(_DF17);

                byte[] _DF14 = ByteUtils.getTLVData("DF14", emvAidPara.getDDOL_Length(), emvAidPara.getDDOL());
                bos.write(_DF14);


                if ((emvAidPara.getTermCap()[1] & 0x40) > 0) {
                    byte[] _DF18 = ByteUtils.getTLVData("DF18", 1, new byte[]{(byte) 0x01});
                    bos.write(_DF18);
                } else {
                    byte[] _DF18 = ByteUtils.getTLVData("DF18", 1, new byte[]{(byte) 0x00});
                    bos.write(_DF18);
                }

                byte[] _9F7B = ByteUtils.getTLVData("9F7B", emvAidPara.getEC_TFL().length, emvAidPara.getEC_TFL());
                bos.write(_9F7B);

                byte[] _DF19 = ByteUtils.getTLVData("DF19", emvAidPara.getRFOfflineLimit().length, emvAidPara.getRFOfflineLimit());
                bos.write(_DF19);

                byte[] _DF20 = ByteUtils.getTLVData("DF20", emvAidPara.getRFTransLimit().length, emvAidPara.getRFTransLimit());
                bos.write(_DF20);

                byte[] _DF21 = ByteUtils.getTLVData("DF21", emvAidPara.getRFCVMLimit().length, emvAidPara.getRFCVMLimit());
                bos.write(_DF21);

                byte[] mergeAid = bos.toByteArray();
                log.debug("aid {}", ByteUtils.byteArray2HexString(mergeAid));
                aidList.add(mergeAid);

                //创建新节点并添加至aid节点
                Element aidItem = xmlCreater.createElement(aidElement, "aidItem");
                xmlCreater.createAttribute(aidItem, "aid", ByteUtils.byteArray2HexString(emvAidPara.getAID()));
                xmlCreater.createAttribute(aidItem, "getAID_Length", emvAidPara.getAID_Length() + "");

                Element aiditemDF01 = xmlCreater.createElement(aidItem, "item",
                        ByteUtils.byteArray2HexString(new byte[]{emvAidPara.getAppSelIndicator()}));
                xmlCreater.createAttribute(aiditemDF01, "tag", "getAppSelIndicator");

                Element aiditem9F09 = xmlCreater.createElement(aidItem, "item",
                        ByteUtils.byteArray2HexString(emvAidPara.getTermAppVer()));
                xmlCreater.createAttribute(aiditem9F09, "tag", "getTermAppVer");

                Element aiditemDF11 = xmlCreater.createElement(aidItem, "item",
                        ByteUtils.byteArray2HexString(emvAidPara.getTAC_Default()));
                xmlCreater.createAttribute(aiditemDF11, "tag", "getTAC_Default");

                Element aiditemDF12 = xmlCreater.createElement(aidItem, "item",
                        ByteUtils.byteArray2HexString(emvAidPara.getTAC_Online()));
                xmlCreater.createAttribute(aiditemDF12, "tag", "getTAC_Online");

                Element aiditemDF13 = xmlCreater.createElement(aidItem, "item",
                        ByteUtils.byteArray2HexString(emvAidPara.getTAC_Denial()));
                xmlCreater.createAttribute(aiditemDF13, "tag", "getTAC_Denial");

                Element aiditem9F1B;
                Element aiditemDF15;
                Element aiditemDF16;
                Element aiditemDF17;
                if (ByteUtils.byteArray2HexString(emvAidPara.getAID()).substring(0, 10).equals("a000000333")) {//国内
                    aiditem9F1B = xmlCreater.createElement(aidItem, "item",
                            ByteUtils.byteArray2HexString(emvAidPara.getTFL_Domestic()));
                    xmlCreater.createAttribute(aiditem9F1B, "tag", "getTFL_Domestic");

                    aiditemDF15 = xmlCreater.createElement(aidItem, "item",
                            ByteUtils.byteArray2HexString(emvAidPara.getThresholdValueDomestic()));
                    xmlCreater.createAttribute(aiditemDF15, "tag", "getThresholdValueDomestic");

                    aiditemDF16 = xmlCreater.createElement(aidItem, "item",
                            ByteUtils.byteArray2HexString(new byte[]{emvAidPara.getMaxTargetDomestic()}));
                    xmlCreater.createAttribute(aiditemDF16, "tag", "getMaxTargetDomestic");

                    aiditemDF17 = xmlCreater.createElement(aidItem, "item",
                            ByteUtils.byteArray2HexString(new byte[]{emvAidPara.getTargetPercentageDomestic()}));
                    xmlCreater.createAttribute(aiditemDF17, "tag", "getTargetPercentageDomestic");

                } else {//国际
                    aiditem9F1B = xmlCreater.createElement(aidItem, "item",
                            ByteUtils.byteArray2HexString(emvAidPara.getTFL_International()));
                    xmlCreater.createAttribute(aiditem9F1B, "tag", "getTFL_International");

                    aiditemDF15 = xmlCreater.createElement(aidItem, "item",
                            ByteUtils.byteArray2HexString(emvAidPara.getThresholdValueInt()));
                    xmlCreater.createAttribute(aiditemDF15, "tag", "getThresholdValueInt");

                    aiditemDF16 = xmlCreater.createElement(aidItem, "item",
                            ByteUtils.byteArray2HexString(new byte[]{emvAidPara.getMaxTargetPercentageInt()}));
                    xmlCreater.createAttribute(aiditemDF16, "tag", "getMaxTargetPercentageInt");

                    aiditemDF17 = xmlCreater.createElement(aidItem, "item",
                            ByteUtils.byteArray2HexString(new byte[]{emvAidPara.getTargetPercentageInt()}));
                    xmlCreater.createAttribute(aiditemDF17, "tag", "getTargetPercentageInt");
                }

                Element aiditemDF14 = xmlCreater.createElement(aidItem, "item",
                        ByteUtils.byteArray2HexString(emvAidPara.getDDOL()));
                xmlCreater.createAttribute(aiditemDF14, "tag", "getDDOL");
                xmlCreater.createAttribute(aiditemDF14, "getDDOL_Length", emvAidPara.getDDOL_Length() + "");

                Element aiditemDF18 = xmlCreater.createElement(aidItem, "item",
                        ByteUtils.byteArray2HexString(emvAidPara.getTermCap()));
                xmlCreater.createAttribute(aiditemDF18, "tag", "getTermCap");


                Element aiditem9F7B = xmlCreater.createElement(aidItem, "item",
                        ByteUtils.byteArray2HexString(emvAidPara.getEC_TFL()));
                xmlCreater.createAttribute(aiditem9F7B, "tag", "getEC_TFL");

                Element aiditemDF19 = xmlCreater.createElement(aidItem, "item",
                        ByteUtils.byteArray2HexString(emvAidPara.getRFOfflineLimit()));
                xmlCreater.createAttribute(aiditemDF19, "tag", "getRFOfflineLimit");

                Element aiditemDF20 = xmlCreater.createElement(aidItem, "item",
                        ByteUtils.byteArray2HexString(emvAidPara.getRFTransLimit()));
                xmlCreater.createAttribute(aiditemDF20, "tag", "getRFTransLimit");

                Element aiditemDF21 = xmlCreater.createElement(aidItem, "item",
                        ByteUtils.byteArray2HexString(emvAidPara.getRFCVMLimit()));
                xmlCreater.createAttribute(aiditemDF21, "tag", "getRFCVMLimit");

                xmlCreater.buildXmlFile();
                log.debug("save xml done");
            }
            bos.close();
            bos = null;
            int result = sdkEmvHandler.setAidParaList(aidList);
            if (result == SdkResult.Success) {
                return ServiceResult.Success;
            } else {
                return ServiceResult.Fail;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ServiceResult.Emv_PARA_ERR;
        }
    }

    /**
     * 加载EMV公钥列表
     * @param capkList
     * @return
     * @throws RemoteException
     */
    @Override
    public int setCAPKList(List<EmvCapk> capkList) throws RemoteException {
        log.info("call setCAPKList");
        try {
            if (capkList == null || capkList.size() == 0) return ServiceResult.Param_In_Invalid;

            String bussinessId = mBussinessId;
            String filesPath = context.getFilesDir().getAbsolutePath();

            String dirPath1 = filesPath + "/emv_data/";
            if (!FileUtils.isFileExist(dirPath1)) {
                log.debug("dirPath1 not exist,creat dirPath1:" + dirPath1);
                FileUtils.newFolder(dirPath1);
            }

            String dirPath2 = dirPath1 + bussinessId;
            if (!FileUtils.isFileExist(dirPath2)) {
                log.debug("dirPath2 not exist,creat dirPath2:" + dirPath2);
                FileUtils.newFolder(dirPath2);
            }

//            String filePath = dirPath2 + "/emv_file.xml";
            String filePath = dirPath2 + "/emv_capk_file.xml";
            XmlCreater xmlCreater = new XmlCreater(filePath);
            Element capkElement;
            Element emv = xmlCreater.createRootElement("emv");
            if (!FileUtils.isFileExist(filePath)) {
                log.debug("recreate emv_file.xml");
                capkElement = xmlCreater.createElement(emv, "capkElement");
            } else {
                log.debug("modify xml");
                //获取XML的dom
                Document doc = xmlCreater.getDoc();

                //获取根节点下的指定子节点列表
                Element[] cfgs = XmlOper.getElementsByName(emv, "capkElement");

                if (cfgs.length > 0) {
                    capkElement = cfgs[0];
                    //删除aid节点下所有子节点
                    XmlOper.removeElement(capkElement, "capkItem");
                } else {
                    //新建aid节点
                    capkElement = xmlCreater.createElement(emv, "capkElement");
                }

                //设置dom
                xmlCreater.setDoc(doc);
            }
            log.debug("add capk count:" + capkList.size());
            List<byte[]> myCapkList = new ArrayList<>();
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            for (EmvCapk emvCapk : capkList) {
                if (emvCapk.getRID() == null || emvCapk.getLengthOfCAPKExponent() == 0
                        || emvCapk.getLengthOfCAPKModulus() == 0) {
                    return ServiceResult.Emv_PARA_ERR;
                }
                log.debug("\nRID:" + ByteUtils.byteArray2HexStringWithSpace(emvCapk.getRID())
                        + "\nCA_PKIndex:" + ByteUtils.byteArray2HexStringWithSpace(new byte[]{emvCapk.getCA_PKIndex()})
                        + "\nCA_HashAlgoIndicator:" + ByteUtils.byteArray2HexStringWithSpace(new byte[]{emvCapk.getCA_HashAlgoIndicator()})
                        + "\nCA_PKAlgoIndicator:" + ByteUtils.byteArray2HexStringWithSpace(new byte[]{emvCapk.getCA_PKAlgoIndicator()})
                        + "\nLengthOfCAPKModulus:" + emvCapk.getLengthOfCAPKModulus()
                        + "\nCAPKModulus:" + ByteUtils.byteArray2HexStringWithSpace(emvCapk.getCAPKModulus())
                        + "\nLengthOfCAPKExponent:" + emvCapk.getLengthOfCAPKExponent()
                        + "\nCAPKExponent:" + ByteUtils.byteArray2HexStringWithSpace(emvCapk.getCAPKExponent())
                        + "\nChecksumHash:" + ByteUtils.byteArray2HexStringWithSpace(emvCapk.getChecksumHash())
                        + "\nCAPKExpDate:" + ByteUtils.byteArray2HexStringWithSpace(emvCapk.getCAPKExpDate())
                );

                bos.reset();
                byte[] _9F06 = ByteUtils.getTLVData("9F06", emvCapk.getRID().length, emvCapk.getRID());
                bos.write(_9F06);

                byte[] _9F22 = ByteUtils.getTLVData("9F22", 1, new byte[]{emvCapk.getCA_PKIndex()});
                bos.write(_9F22);

                byte[] _DF05 = ByteUtils.getTLVData("DF05", emvCapk.getCAPKExpDate().length, emvCapk.getCAPKExpDate());
                if (emvCapk.getCAPKExpDate().length == 3) {
                    //有效期只下发3个字节的时候,补到4个字节
                    byte[] tmp = new byte[4];
                    tmp[0] = 0x20;
                    System.arraycopy(emvCapk.getCAPKExpDate(), 0, tmp, 1, emvCapk.getCAPKExpDate().length);
                    _DF05 = ByteUtils.getTLVData("DF05", tmp.length, tmp);
                }
                bos.write(_DF05);

                byte[] _DF06 = ByteUtils.getTLVData("DF06", 1, new byte[]{emvCapk.getCA_HashAlgoIndicator()});
                bos.write(_DF06);

                byte[] _DF07 = ByteUtils.getTLVData("DF07", 1, new byte[]{emvCapk.getCA_PKAlgoIndicator()});
                bos.write(_DF07);

                byte[] _DF02 = ByteUtils.getTLVData("DF02", emvCapk.getLengthOfCAPKModulus(), emvCapk.getCAPKModulus());
                bos.write(_DF02);

                byte[] _DF04 = ByteUtils.getTLVData("DF04", emvCapk.getLengthOfCAPKExponent(), emvCapk.getCAPKExponent());
                bos.write(_DF04);

                byte[] _DF03 = ByteUtils.getTLVData("DF03", emvCapk.getChecksumHash().length, emvCapk.getChecksumHash());
                bos.write(_DF03);

                byte[] mergeTlv = bos.toByteArray();
                log.debug("capk {}", ByteUtils.byteArray2HexString(mergeTlv));
                myCapkList.add(mergeTlv);

                //创建新节点并添加至capkItem节点
                Element capkItem = xmlCreater.createElement(capkElement, "capkItem");
                xmlCreater.createAttribute(capkItem, "rid", ByteUtils.byteArray2HexString(emvCapk.getRID()));
                xmlCreater.createAttribute(capkItem, "getCA_PKIndex", ByteUtils.byteArray2HexString(new byte[]{emvCapk.getCA_PKIndex()}));

                Element capkitemDF05 = xmlCreater.createElement(capkItem, "item",
                        ByteUtils.byteArray2HexString(emvCapk.getCAPKExpDate()));
                xmlCreater.createAttribute(capkitemDF05, "tag", "getCAPKExpDate");

                Element capkitemDF06 = xmlCreater.createElement(capkItem, "item",
                        ByteUtils.byteArray2HexString(new byte[]{emvCapk.getCA_HashAlgoIndicator()}));
                xmlCreater.createAttribute(capkitemDF06, "tag", "getCA_HashAlgoIndicator");

                Element capkitemDF07 = xmlCreater.createElement(capkItem, "item",
                        ByteUtils.byteArray2HexString(new byte[]{emvCapk.getCA_PKAlgoIndicator()}));
                xmlCreater.createAttribute(capkitemDF07, "tag", "getCA_PKAlgoIndicator");

                Element capkitemDF02 = xmlCreater.createElement(capkItem, "item",
                        ByteUtils.byteArray2HexString(emvCapk.getCAPKModulus()));
                xmlCreater.createAttribute(capkitemDF02, "tag", "getCAPKModulus");
                xmlCreater.createAttribute(capkitemDF02, "getLengthOfCAPKModulus", emvCapk.getLengthOfCAPKModulus() + "");

                Element capkitemDF04 = xmlCreater.createElement(capkItem, "item",
                        ByteUtils.byteArray2HexString(emvCapk.getCAPKExponent()));
                xmlCreater.createAttribute(capkitemDF04, "tag", "getCAPKExponent");
                xmlCreater.createAttribute(capkitemDF04, "getLengthOfCAPKExponent", emvCapk.getLengthOfCAPKExponent() + "");

                Element capkitemDF03 = xmlCreater.createElement(capkItem, "item",
                        ByteUtils.byteArray2HexString(emvCapk.getChecksumHash()));
                xmlCreater.createAttribute(capkitemDF03, "tag", "getChecksumHash");

                xmlCreater.buildXmlFile();
                log.debug("save xml done");
            }
            bos.close();
            bos = null;
            int result = sdkEmvHandler.setCAPKList(myCapkList);
            if (result == SdkResult.Success) {
                return ServiceResult.Success;
            } else {
                return ServiceResult.Fail;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ServiceResult.Emv_PARA_ERR;
        }
    }

    @Override
    public List<EmvCapk> getCapkList() throws RemoteException {
        log.info("call getCapkList");
        String bussinessId = mBussinessId;
        String filePath = context.getFilesDir().getAbsolutePath()
                + File.separator + "emv_data"
                + File.separator + bussinessId
//                + File.separator + "emv_file.xml";
                + File.separator + "emv_capk_file.xml";

        if (!FileUtils.isFileExist(filePath)) {
//            log.debug("not exist emv_file.xml");
            log.debug("not exist emv_capk_file.xml");
            return null;
        }
        log.debug("exist xml");
        List<EmvCapk> list = new ArrayList<>();
        //获取根节点
        XMLBuilder xmlBuilder = new XMLBuilder(filePath);
        Element emv = xmlBuilder.getRoot();

        //获取根节点下的指定子节点列表
        Element[] cfgs = XmlOper.getElementsByName(emv, "capkElement");
        Element capkElement;
        if (cfgs.length > 0) {
            capkElement = cfgs[0];
        } else {
            return null;
        }

        Element[] capkItems = XmlOper.getElementsByName(capkElement, "capkItem");
        for (Element capkItem : capkItems) {
            EmvCapk emvCapk = new EmvCapk();
            emvCapk.setRID(ByteUtils.hexString2ByteArray(XmlOper.getElementAttr(capkItem, "rid")));
            emvCapk.setCA_PKIndex(ByteUtils.hexString2Byte(XmlOper.getElementAttr(capkItem, "getCA_PKIndex")));

            Element[] items = XmlOper.getElementsByName(capkItem, "item");
            log.trace("items length:" + items.length);
            for (Element item : items) {
                if (XmlOper.getElementAttr(item, "tag").equals("getCAPKExpDate")) {
                    byte[] tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getCAPKExpDate:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvCapk.setCAPKExpDate(tmp);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getCA_HashAlgoIndicator")) {
                    byte[] tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getCA_HashAlgoIndicator:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvCapk.setCA_HashAlgoIndicator(tmp[0]);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getCA_PKAlgoIndicator")) {
                    byte[] tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getCA_PKAlgoIndicator:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvCapk.setCA_PKAlgoIndicator(tmp[0]);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getCAPKModulus")) {
                    byte[] tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getCAPKModulus:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvCapk.setCAPKModulus(tmp);
                        String len = XmlOper.getElementAttr(item, "getLengthOfCAPKModulus");
                        if (!TextUtils.isEmpty(len)) {
                            emvCapk.setLengthOfCAPKModulus(Integer.parseInt(len));
                        }
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getCAPKExponent")) {
                    byte[] tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getCAPKExponent:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvCapk.setCAPKExponent(tmp);
                        String len = XmlOper.getElementAttr(item, "getLengthOfCAPKExponent");
                        if (!TextUtils.isEmpty(len)) {
                            emvCapk.setLengthOfCAPKExponent(Integer.parseInt(len));
                        }
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getChecksumHash")) {
                    byte[] tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getChecksumHash:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvCapk.setChecksumHash(tmp);
                    }
                }

            }
            list.add(emvCapk);
        }
        return list;
    }

    @Override
    public List<EmvAidPara> getAidParaList() throws RemoteException {
        log.info("call getAidParaList");
        String bussinessId = mBussinessId;
        String filesPath = context.getFilesDir().getAbsolutePath();
        String dirPath1 = filesPath + "/emv_data/";
        String dirPath2 = dirPath1 + bussinessId;
//        String filePath = dirPath2 + "/emv_file.xml";
        String filePath = dirPath2 + "/emv_aid_file.xml";

        List<EmvAidPara> list = new ArrayList<>();
        if (!FileUtils.isFileExist(filePath)) {
//            log.debug("not exist emv_file.xml");
            log.debug("not exist emv_aid_file.xml");
            return null;
        }
        log.debug("exist xml");
        //获取根节点
        XMLBuilder xmlBuilder = new XMLBuilder(filePath);
        Element emv = xmlBuilder.getRoot();

        //获取XML的dom
        Document doc = xmlBuilder.getDoc();

        //获取根节点下的指定子节点列表
        Element[] cfgs = XmlOper.getElementsByName(emv, "aidElement");
        Element aidElement;
        if (cfgs.length > 0) {
            aidElement = cfgs[0];
        } else {
            return null;
        }
        byte[] tmp;
        Element[] aidItems = XmlOper.getElementsByName(aidElement, "aidItem");
        log.debug("aid num {}", aidItems.length);
        for (Element aidItem : aidItems) {
            EmvAidPara emvAidPara = new EmvAidPara();
            emvAidPara.setAID(ByteUtils.hexString2ByteArray(XmlOper.getElementAttr(aidItem, "aid")));
            emvAidPara.setAID_Length(Integer.parseInt(XmlOper.getElementAttr(aidItem, "getAID_Length")));

            Element[] items = XmlOper.getElementsByName(aidItem, "item");
            for (Element item : items) {
                if (XmlOper.getElementAttr(item, "tag").equals("getAppSelIndicator")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getAppSelIndicator:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setAppSelIndicator(tmp[0]);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getTermAppVer")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getTermAppVer:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setTermAppVer(tmp);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getTAC_Default")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getTAC_Default:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setTAC_Default(tmp);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getTAC_Online")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getTAC_Online:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setTAC_Online(tmp);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getTAC_Denial")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getTAC_Denial:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setTAC_Denial(tmp);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getTFL_Domestic")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getTFL_Domestic:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setTFL_Domestic(tmp);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getThresholdValueDomestic")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getThresholdValueDomestic:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setThresholdValueDomestic(tmp);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getMaxTargetDomestic")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getMaxTargetDomestic:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setMaxTargetDomestic(tmp[0]);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getTargetPercentageDomestic")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getTargetPercentageDomestic:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setTargetPercentageDomestic(tmp[0]);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getTFL_International")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getTFL_International:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setTFL_International(tmp);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getThresholdValueInt")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getThresholdValueInt:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setThresholdValueInt(tmp);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getMaxTargetPercentageInt")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getMaxTargetPercentageInt:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setMaxTargetPercentageInt(tmp[0]);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getTargetPercentageInt")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getTargetPercentageInt:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setTargetPercentageInt(tmp[0]);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getDDOL")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getDDOL:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setDDOL(tmp);
                        byte[] len = ByteUtils.hexString2ByteArray(XmlOper.getElementAttr(item, "getDDOL_Length"));
                        if (len != null && len.length > 0) {
                            emvAidPara.setDDOL_Length(len[0]);
                        }
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getTermCap")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getTermCap:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setTermCap(tmp);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getEC_TFL")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getEC_TFL:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setEC_TFL(tmp);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getRFOfflineLimit")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getRFOfflineLimit:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setRFOfflineLimit(tmp);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getRFTransLimit")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getRFTransLimit:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setRFTransLimit(tmp);
                    }
                }
                if (XmlOper.getElementAttr(item, "tag").equals("getRFCVMLimit")) {
                    tmp = ByteUtils.hexString2ByteArray(XmlOper.getElementValue(item));
                    log.trace("getRFCVMLimit:" + XmlOper.getElementValue(item));
                    if (tmp != null && tmp.length > 0) {
                        emvAidPara.setRFCVMLimit(tmp);
                    }
                }

            }
            list.add(emvAidPara);
        }
        return list;
    }

    @Override
    public byte[] getTlvs(byte[] tag, int pathId) throws RemoteException {
        log.info("call getTlvs");
        if (tag == null || tag.length == 0) return null;
        if (pathId != EmvDataSource.FROMKERNEL && pathId != EmvDataSource.FROMCARD) return null;
        byte[] tagData;
        log.debug("tag {} form {}", ByteUtils.byteArray2HexString(tag), pathId == EmvDataSource.FROMCARD ? "card" : "kernel");
        tagData = sdkEmvHandler.getTlv(tag, pathId == EmvDataSource.FROMKERNEL ? EmvDataSourceEnum.FROM_KERNEL : EmvDataSourceEnum.FROM_CARD);
        if (tagData != null) {
            log.debug("tag {},data {}", ByteUtils.byteArray2HexString(tag), ByteUtils.byteArray2HexString(tagData));
            return tagData;
        } else {
            if(pathId == EmvDataSource.FROMCARD){
                tagData = sdkEmvHandler.getTlv(tag, EmvDataSourceEnum.FROM_KERNEL);
                if(tagData != null) {
                    log.debug("tag {},data {}", ByteUtils.byteArray2HexString(tag), ByteUtils.byteArray2HexString(tagData));
                    return tagData;
                }
            }
            log.debug("data null");
        }
        return new byte[0];
    }

    @Override
    public int setTlv(byte[] tag, byte[] value) throws RemoteException {
        log.info("call setTlv");
        if (tag == null || value == null) return ServiceResult.Param_In_Invalid;
        byte[] tlv = ByteUtils.getTLVData(ByteUtils.byteArray2HexString(tag),
                value.length,
                value);
        log.debug("tlv" + ByteUtils.byteArray2HexStringWithSpace(tlv));
        int result = sdkEmvHandler.setTlv(tag, value);
        if (result == SdkResult.Success) {
            return ServiceResult.Success;
        } else {
            return ServiceResult.Fail;
        }
    }

    @Override
    public int getEmvCardLog(int channelType, final OnEmvProcessListener listener) throws RemoteException {
        log.info("call getEmvCardLog");
        if (listener == null) return ServiceResult.Param_In_Invalid;
        if (channelType != EmvChannelType.FROM_ICC && channelType != EmvChannelType.FROM_PICC) {
            return ServiceResult.Param_In_Invalid;
        }

//        if(true == mIsBusy)
//            return ServiceResult.Fail;
//        mIsBusy = true;

        EmvChannelTypeEnum emvChannelTypeEnum = channelType == EmvChannelType.FROM_ICC ? EmvChannelTypeEnum.FROM_ICC : EmvChannelTypeEnum.FROM_PICC;
        int result = sdkEmvHandler.getEmvCardLog(emvChannelTypeEnum, new com.nexgo.oaf.apiv3.emv.OnEmvProcessListener() {

            @Override
            public void onRequestAmount() {

            }

            @Override
            public void onSelApp(List<String> list, List<CandidateAppInfoEntity> list1, boolean b) {
                log.info("call getEmvCardLog onSelApp");
                int defaultSelAppIndex = getDefaultSelAppIndex(list1);
                if (defaultSelAppIndex > 0)
                    sdkEmvHandler.onSetSelAppResponse(defaultSelAppIndex);
                else {
                    try {
                        listener.onSelApp(list, b);
                    } catch (RemoteException e) {
                        sdkEmvHandler.onSetSelAppResponse(-1);
                    }
                }
            }

            @Override
            public void onConfirmEcSwitch() {

            }

            @Override
            public void onConfirmCardNo(CardInfoEntity cardInfoEntity) {

            }

            @Override
            public void onCardHolderInputPin(boolean b, int i) {

            }

            @Override
            public void onCertVerify(String s, String s1) {

            }

            @Override
            public void onOnlineProc() {

            }

            @Override
            public void onReadCardAgain() {

            }

            @Override
            public void onAfterFinalSelectedApp() {

            }


            @Override
            public void onFinish(int i, EmvProcessResultEntity emvProcessResultEntity) {
                try {
                    if (i == SdkResult.Success) {
                        if (emvProcessResultEntity != null) {
                            List<EmvCardLogEntity> emvLogList = emvProcessResultEntity.getEmvLog();
                            Bundle bundle = new Bundle();
                            ArrayList<EmvCardLog> list = new ArrayList<>();
                            for (EmvCardLogEntity emvLog : emvLogList) {
                                EmvCardLog emvCardLog = new EmvCardLog();
                                emvCardLog.setTransDate(emvLog.getTransDate());
                                emvCardLog.setDateExist(emvLog.getTransDate() != null);
                                emvCardLog.setTransTime(emvLog.getTransTime());
                                emvCardLog.setTimeExist(emvLog.getTransTime() != null);
                                emvCardLog.setAmt(emvLog.getAmt());
                                emvCardLog.setAmtExist(emvLog.getAmt() != null);
                                emvCardLog.setOtherAmt(emvLog.getOtherAmt());
                                emvCardLog.setOtherAmtExist(emvLog.getOtherAmt() != null);
                                emvCardLog.setCntCode(emvLog.getCntCode());
                                emvCardLog.setCntCodeExist(emvLog.getCntCode() != null);
                                emvCardLog.setCurCode(emvLog.getCurCode());
                                emvCardLog.setCurExist(emvLog.getCurCode() != null);
                                emvCardLog.setMerName(new String(ByteUtils.hexString2ByteArray(emvLog.getMerName())));
                                emvCardLog.setMerNameExist(emvLog.getMerName() != null);
                                emvCardLog.setServeType(emvLog.getServeType());
                                emvCardLog.setIs9Cexist(emvLog.getServeType() != null);
                                emvCardLog.setAtc(emvLog.getAtc());
                                emvCardLog.setAtcExist(emvLog.getAtc() != null);
                                emvCardLog.setTlvLen(256);
                                emvCardLog.setTlv(new byte[256]);
                                list.add(emvCardLog);
                                log.debug("getTransDate {}", emvCardLog.getTransDate());
                                log.debug("getTransTime {}", emvCardLog.getTransTime());
                                log.debug("getAmt {}", emvCardLog.getAmt());
                                log.debug("getOtherAmt {}", emvCardLog.getOtherAmt());
                                log.debug("getCntCode {}", emvCardLog.getCntCode());
                                log.debug("getCurCode {}", emvCardLog.getCurCode());
                                log.debug("getMerName {}", emvCardLog.getMerName());
                                log.debug("getServeType {}", emvCardLog.getServeType());
                                log.debug("isIs9Cexist {}", emvCardLog.isIs9Cexist());
                                log.debug("getAtc {}", emvCardLog.getAtc());
                            }
                            bundle.putParcelableArrayList(EmvProcessResult.EMVLOG, list);
                            listener.onFinish(ServiceResult.Success, bundle);
                            return;
                        }
                    }
                    listener.onFinish(emvResultConvert(i), null);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
//                finally {
//                    mIsBusy = false;
//                }
            }
        });
        if (result == SdkResult.Success) {
            return ServiceResult.Success;
        } else {
            return ServiceResult.Fail;
        }
    }


    @Override
    public int clearLog() throws RemoteException {
        log.info("call clearLog");
        int result = sdkEmvHandler.clearLog();
        if (result == SdkResult.Success) {
            return ServiceResult.Success;
        } else {
            return ServiceResult.Fail;
        }
    }

    @Override
    public int emvGetEcBalance(final OnEmvProcessListener listener, int channelType) throws RemoteException {
        log.info("call emvGetEcBalance");
        if (listener == null) return ServiceResult.Param_In_Invalid;
        if (channelType != EmvChannelType.FROM_ICC && channelType != EmvChannelType.FROM_PICC)
            return ServiceResult.Param_In_Invalid;

//        if(true == mIsBusy)
//            return ServiceResult.Fail;
//        mIsBusy = true;

//        if (channelType == EmvChannelType.FROM_PICC) {
//            sdkCPUcardHandler = GlobalDataHolder.getInstance().getDeviceEngine().getCPUCardHandler(CardSlotTypeEnum.RF);
//            sdkCPUcardHandler.active();
//        } else {
//            sdkCPUcardHandler = GlobalDataHolder.getInstance().getDeviceEngine().getCPUCardHandler(CardSlotTypeEnum.ICC1);
//            sdkCPUcardHandler.powerOn(new byte[64]);
//        }
        EmvChannelTypeEnum emvChannelTypeEnum = channelType == EmvChannelType.FROM_ICC ? EmvChannelTypeEnum.FROM_ICC : EmvChannelTypeEnum.FROM_PICC;
        int result = sdkEmvHandler.emvGetEcBalance(emvChannelTypeEnum, new com.nexgo.oaf.apiv3.emv.OnEmvProcessListener() {

            @Override
            public void onRequestAmount() {

            }

            @Override
            public void onSelApp(List<String> list, List<CandidateAppInfoEntity> list1, boolean b) {

            }

            @Override
            public void onConfirmEcSwitch() {
                sdkEmvHandler.onSetConfirmEcSwitchResponse(true);
            }

            @Override
            public void onConfirmCardNo(CardInfoEntity cardInfoEntity) {

            }

            @Override
            public void onCardHolderInputPin(boolean b, int i) {

            }

            @Override
            public void onCertVerify(String s, String s1) {

            }

            @Override
            public void onOnlineProc() {

            }

            @Override
            public void onReadCardAgain() {

            }

            @Override
            public void onAfterFinalSelectedApp() {

            }

            @Override
            public void onFinish(int i, EmvProcessResultEntity emvProcessResultEntity) {
                try {
                    if (i == SdkResult.Success) {
                        byte[] balance = emvProcessResultEntity.getEcBalance();
                        if (balance != null) {
                            Bundle bundle = new Bundle();
                            //转成12个字节的asc码
                            bundle.putByteArray(EmvProcessResult.ECBALANCE, ByteUtils.string2ASCIIByteArray(ByteUtils.byteArray2HexString(balance)));
                            listener.onFinish(ServiceResult.Success, bundle);
                            return;
                        }
                    }
                    listener.onFinish(emvResultConvert(i), null);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
//                finally {
//                    mIsBusy = false;
//                }
            }
        });
        if (result == SdkResult.Success) {
            return ServiceResult.Success;
        } else {
            return ServiceResult.Fail;
        }
    }

    @Override
    public void onSetSelAppResponse(int selResult) throws RemoteException {
        log.info("call onSetSelAppResponse {}", selResult);
//        sdkEmvHandler.onSetSelAppResponse(selResult);
        //银商201706确认传入应用索引号从0开始，我们sdk从1还是，需要转换
        if (selResult < 0)
            sdkEmvHandler.onSetSelAppResponse(-1);
        else
            sdkEmvHandler.onSetSelAppResponse(selResult + 1);
    }

    @Override
    public void onSetConfirmCardNoResponse(boolean isConfirm) throws RemoteException {
        log.info("call onSetConfirmCardNoResponse");
        sdkEmvHandler.onSetConfirmCardNoResponse(isConfirm);
    }

    @Override
    public void onSetCertVerifyResponse(boolean isVerify) throws RemoteException {
        log.info("call onSetCertVerifyResponse");
        sdkEmvHandler.onSetCertVerifyResponse(isVerify);
    }

    @Override
    public void onSetOnlineProcResponse(int retCode, Bundle data) throws RemoteException {
        log.info("call onSetOnlineProcResponse");
        try {
            EmvOnlineResultEntity emvOnlineResultEntity = new EmvOnlineResultEntity();
            if (data != null) {
                for (String key : data.keySet()) {
                    if (data.get(key) instanceof byte[]) {
                        log.debug("key {},value {}", key, ByteUtils.byteArray2HexString(data.getByteArray(key)));
                    } else {
                        log.debug("key {},value {}", key, data.get(key));
                    }

                    switch (key) {
                        case EmvOnlineResult.REJCODE:
                            emvOnlineResultEntity.setRejCode(data.getString(EmvOnlineResult.REJCODE));
                            break;
                        case EmvOnlineResult.AUTHCODE:
                            emvOnlineResultEntity.setAuthCode(data.getString(EmvOnlineResult.AUTHCODE));
                            break;
                        case EmvOnlineResult.RECVF55:
                            emvOnlineResultEntity.setRecvField55(data.getByteArray(EmvOnlineResult.RECVF55));
                            break;
                    }
                }
            }
            int result;
            if (retCode == EmvOnlineResult.EMV_ONLINE_APPROVE || retCode == EmvOnlineResult.EMV_ONLINE_FAIL) {
                result = SdkResult.Success;
            } else {
                result = SdkResult.Fail;
            }
            sdkEmvHandler.onSetOnlineProcResponse(result, emvOnlineResultEntity);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onSetAIDParameterResponse(EmvAidPara aid) throws RemoteException {
        log.info("call onSetAIDParameterResponse");
    }

    @Override
    public void onSetCAPubkeyResponse(EmvCapk capk) throws RemoteException {
        log.info("call onSetCAPubkeyResponse");
    }

    @Override
    public void onSetTRiskManageResponse(String result) throws RemoteException {
        log.info("call onSetTRiskManageResponse result {}", result);
    }

    @Override
    public String getRFErrorCode() throws RemoteException {
        log.info("call getRFErrorCode");
        QpbocErrCodeEnum errCode = sdkEmvHandler.getQPBOCErrCode();
        if (null == errCode || QpbocErrCodeEnum.FOK == errCode)
            return null;
        else {
            String rslt = errCode.name();
            log.debug("getRFErrorCode result {}", rslt);
            return rslt;
//            return errCode.name();
        }

    }
}
